// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Engine/World.h"

#include "LyraEquipmentInstance.generated.h"

class AActor;
class APawn;
struct FFrame;
struct FLyraEquipmentActorToSpawn;

/**
 * ULyraEquipmentInstance
 * 生成并应用于 pawn 的装备实例
 */
UCLASS(BlueprintType, Blueprintable)
class ULyraEquipmentInstance : public UObject
{
	GENERATED_BODY()

public:
	ULyraEquipmentInstance(const FObjectInitializer& ObjectInitializer = FObjectInitializer::Get());

	//~UObject 接口
	virtual bool IsSupportedForNetworking() const override { return true; } // 支持网络复制
	virtual UWorld* GetWorld() const override final; // 获取世界上下文
	//~UObject 接口结束

	UFUNCTION(BlueprintPure, Category=Equipment)
	UObject* GetInstigator() const { return Instigator; } // 获取发起者

	void SetInstigator(UObject* InInstigator) { Instigator = InInstigator; } // 设置发起者

	UFUNCTION(BlueprintPure, Category=Equipment)
	APawn* GetPawn() const; // 获取所属 Pawn

	UFUNCTION(BlueprintPure, Category=Equipment, meta=(DeterminesOutputType=PawnType))
	APawn* GetTypedPawn(TSubclassOf<APawn> PawnType) const; // 获取指定类型的 Pawn

	UFUNCTION(BlueprintPure, Category=Equipment)
	TArray<AActor*> GetSpawnedActors() const { return SpawnedActors; } // 获取已生成的演员列表

	virtual void SpawnEquipmentActors(const TArray<FLyraEquipmentActorToSpawn>& ActorsToSpawn); // 生成装备演员
	virtual void DestroyEquipmentActors(); // 销毁装备演员

	virtual void OnEquipped(); // 装备时调用
	virtual void OnUnequipped(); // 卸下时调用

protected:
#if UE_WITH_IRIS
	/** 注册所有复制片段 */
	virtual void RegisterReplicationFragments(UE::Net::FFragmentRegistrationContext& Context, UE::Net::EFragmentRegistrationFlags RegistrationFlags) override;
#endif // UE_WITH_IRIS

	UFUNCTION(BlueprintImplementableEvent, Category=Equipment, meta=(DisplayName="OnEquipped"))
	void K2_OnEquipped(); // 蓝图可实现的装备事件

	UFUNCTION(BlueprintImplementableEvent, Category=Equipment, meta=(DisplayName="OnUnequipped"))
	void K2_OnUnequipped(); // 蓝图可实现的卸下事件

private:
	UFUNCTION()
	void OnRep_Instigator(); // 复制通知：发起者

private:
	UPROPERTY(ReplicatedUsing=OnRep_Instigator)
	TObjectPtr<UObject> Instigator; // 发起者对象

	UPROPERTY(Replicated)
	TArray<TObjectPtr<AActor>> SpawnedActors; // 已生成的演员列表
};